<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="generator" content="quarto-1.7.32">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Custom – modelsummary: Data and Model Summaries in R</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
  width: 0.8em;
  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
  vertical-align: middle;
}
/* CSS for syntax highlighting */
html { -webkit-text-size-adjust: 100%; }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
</style>

<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
<script src="../site_libs/quarto-nav/headroom.min.js"></script>
<script src="../site_libs/clipboard/clipboard.min.js"></script>
<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
<script src="../site_libs/quarto-search/fuse.min.js"></script>
<script src="../site_libs/quarto-search/quarto-search.js"></script>
<meta name="quarto:offset" content="../">
<link href="../vignettes/appearance.html" rel="next">
<link href="../vignettes/modelplot.html" rel="prev">
<script src="../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../site_libs/quarto-html/popper.min.js"></script>
<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../site_libs/quarto-html/anchor.min.js"></script>
<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-37eea08aefeeee20ff55810ff984fec1.css" rel="stylesheet" id="quarto-text-highlighting-styles">
<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../site_libs/bootstrap/bootstrap-555d7fa6eb067a0c9d334ac7ef1a20f4.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light"><script id="quarto-search-options" type="application/json">{
  "location": "navbar",
  "copy-button": false,
  "collapse-after": 3,
  "panel-placement": "end",
  "type": "overlay",
  "limit": 50,
  "keyboard-shortcut": [
    "f",
    "/",
    "s"
  ],
  "show-item-context": false,
  "language": {
    "search-no-results-text": "No results",
    "search-matching-documents-text": "matching documents",
    "search-copy-link-title": "Copy link to search",
    "search-hide-matches-text": "Hide additional matches",
    "search-more-match-text": "more match in this document",
    "search-more-matches-text": "more matches in this document",
    "search-clear-button-title": "Clear",
    "search-text-placeholder": "",
    "search-detached-cancel-button-title": "Cancel",
    "search-submit-button-title": "Submit",
    "search-label": "Search"
  }
}</script>
</head>
<body class="nav-sidebar floating nav-fixed quarto-light">

<div id="quarto-search-results"></div>
  <header id="quarto-header" class="headroom fixed-top"><nav class="navbar navbar-expand-lg " data-bs-theme="dark"><div class="navbar-container container-fluid">
      <div class="navbar-brand-container mx-auto">
    <a class="navbar-brand" href="../index.html">
    <span class="navbar-title">modelsummary: Data and Model Summaries in R</span>
    </a>
  </div>
            <div id="quarto-search" class="" title="Search"></div>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" role="menu" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
  <span class="navbar-toggler-icon"></span>
</button>
          <div class="collapse navbar-collapse" id="navbarCollapse">
            <ul class="navbar-nav navbar-nav-scroll ms-auto">
<li class="nav-item">
    <a class="nav-link active" href="../vignettes/get_started.html" aria-current="page"> 
<span class="menu-text">Get started</span></a>
  </li>  
  <li class="nav-item compact">
    <a class="nav-link" href="https://github.com/vincentarelbundock/modelsummary/"> <i class="bi bi-github" role="img" aria-label="modelsummary GitHub">
</i> 
<span class="menu-text"></span></a>
  </li>  
</ul>
</div> <!-- /navcollapse -->
            <div class="quarto-navbar-tools">
</div>
      </div> <!-- /container-fluid -->
    </nav><nav class="quarto-secondary-nav"><div class="container-fluid d-flex">
      <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" role="button" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
        <i class="bi bi-layout-text-sidebar-reverse"></i>
      </button>
        <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="../vignettes/modelsummary_extension.html">Custom</a></li></ol></nav>
        <a class="flex-grow-1" role="navigation" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">      
        </a>
    </div>
  </nav></header><!-- content --><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
<!-- sidebar -->
  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto"><div class="sidebar-menu-container"> 
    <ul class="list-unstyled mt-1">
<li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../vignettes/get_started.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Getting started</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../vignettes/datasummary.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Data Summaries</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../vignettes/modelsummary.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Model Summaries</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../vignettes/modelplot.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Model Plots</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../vignettes/modelsummary_extension.html" class="sidebar-item-text sidebar-link active">
 <span class="menu-text">Custom</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../vignettes/appearance.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Themes and Styles</span></a>
  </div>
</li>
        <li class="sidebar-item sidebar-item-section">
      <div class="sidebar-item-container"> 
            <a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" role="navigation" aria-expanded="false">
 <span class="menu-text">Functions</span></a>
          <a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" role="navigation" aria-expanded="false" aria-label="Toggle section">
            <i class="bi bi-chevron-right ms-2"></i>
          </a> 
      </div>
      <ul id="quarto-sidebar-section-1" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/modelsummary.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>modelsummary</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/modelplot.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>modelplot</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/datasummary.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>datasummary</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/datasummary_skim.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>datasummary_skim</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/datasummary_balance.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>datsummary_balance</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/datasummary_crosstab.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>datasummary_crosstab</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/datasummary_correlation.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>datasummary_correlation</code></span></a>
  </div>
</li>
          <li class="sidebar-item sidebar-item-section">
      <div class="sidebar-item-container"> 
            <a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" role="navigation" aria-expanded="false">
 <span class="menu-text">Formatting</span></a>
          <a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" role="navigation" aria-expanded="false" aria-label="Toggle section">
            <i class="bi bi-chevron-right ms-2"></i>
          </a> 
      </div>
      <ul id="quarto-sidebar-section-2" class="collapse list-unstyled sidebar-section depth2 ">
<li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_decimal.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_decimal</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_equivalence.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_equivalence</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_sci.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_sci</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_significant.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_significant</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_sprintf.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_sprintf</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_statistic.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_statistic</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/fmt_term.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>fmt_term</code></span></a>
  </div>
</li>
      </ul>
</li>
          <li class="sidebar-item sidebar-item-section">
      <div class="sidebar-item-container"> 
            <a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" role="navigation" aria-expanded="false">
 <span class="menu-text">Utilities</span></a>
          <a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" role="navigation" aria-expanded="false" aria-label="Toggle section">
            <i class="bi bi-chevron-right ms-2"></i>
          </a> 
      </div>
      <ul id="quarto-sidebar-section-3" class="collapse list-unstyled sidebar-section depth2 ">
<li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/get_estimates.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>get_estimates</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/get_gof.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>get_gof</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/coef_rename.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>coef_rename</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/dvnames.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>dvnames</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/gof_map.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>gof_map</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/datasummary_correlation_format.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>datasummary_correlation_format</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/config_modelsummary.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>config_modelsummary</code></span></a>
  </div>
</li>
          <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../man/update_modelsummary.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><code>update_modelsummary</code></span></a>
  </div>
</li>
      </ul>
</li>
      </ul>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../NEWS.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">News</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../LICENSE.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">License</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../CITATION.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Citation</span></a>
  </div>
</li>
    </ul>
</div>
</nav><div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
<!-- margin-sidebar -->
    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
        <nav id="TOC" role="doc-toc" class="toc-active"><h2 id="toc-title">On this page</h2>
   
  <ul>
<li><a href="#unsupported-models-modelsummary_list" id="toc-unsupported-models-modelsummary_list" class="nav-link active" data-scroll-target="#unsupported-models-modelsummary_list">Unsupported models: <code>modelsummary_list</code></a></li>
  <li><a href="#unsupported-models-glance-and-tidy" id="toc-unsupported-models-glance-and-tidy" class="nav-link" data-scroll-target="#unsupported-models-glance-and-tidy">Unsupported models: <code>glance</code> and <code>tidy</code></a></li>
  <li><a href="#modifying-information-tidy_custom-and-glance_custom" id="toc-modifying-information-tidy_custom-and-glance_custom" class="nav-link" data-scroll-target="#modifying-information-tidy_custom-and-glance_custom">Modifying information: <code>tidy_custom</code> and <code>glance_custom</code></a></li>
  <li><a href="#new-information-tidy_custom-and-glance_custom" id="toc-new-information-tidy_custom-and-glance_custom" class="nav-link" data-scroll-target="#new-information-tidy_custom-and-glance_custom">New information: <code>tidy_custom</code> and <code>glance_custom</code></a></li>
  <li><a href="#customization-new-model-class" id="toc-customization-new-model-class" class="nav-link" data-scroll-target="#customization-new-model-class">Customization: New model class</a></li>
  <li><a href="#customization-modelsummary_list" id="toc-customization-modelsummary_list" class="nav-link" data-scroll-target="#customization-modelsummary_list">Customization: <code>modelsummary_list</code></a></li>
  </ul></nav>
    </div>
<!-- main -->
<main class="content" id="quarto-document-content"><header id="title-block-header" class="quarto-title-block default"><div class="quarto-title">
<h1 class="title">Custom</h1>
</div>



<div class="quarto-title-meta">

    
  
    
  </div>
  


</header><div class="cell">
<style type="text/css">
.table, th, td {
  font-size: 0.9em;
} 
.table tbody td, .table thead tr {
    white-space: nowrap;
}
</style>
</div>
<div class="cell">
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="va"><a href="https://modelsummary.com">modelsummary</a></span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<section id="unsupported-models-modelsummary_list" class="level1"><h1>Unsupported models: <code>modelsummary_list</code>
</h1>
<p>The simplest way to summarize an unsupported model is to create a <code>modelsummary_list</code> object. This approach is super flexible, but it requires manual intervention, and it can become tedious if you need to summarize many models. The next section shows how to add formal support for an unsupported model type.</p>
<p>A <code>modelsummary_list</code> is a list with two element that conform to the <code>broom</code> package specification: <code>tidy</code> and <code>glance</code>. <code>tidy</code> is a data.frame with at least three columns: <code>term</code>, <code>estimate</code>, and <code>std.error</code>. <code>glance</code> is a data.frame with only a single row, and where each column will be displayed at the bottom of the table in the goodness-of-fit section. Finally, we wrap those two elements in a list and assign it a <code>modelsummary_list</code> class:</p>
<div class="cell">
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">ti</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>  term <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="st">"coef1"</span>, <span class="st">"coef2"</span>, <span class="st">"coef3"</span><span class="op">)</span>,</span>
<span>  estimate <span class="op">=</span> <span class="fl">1</span><span class="op">:</span><span class="fl">3</span>,</span>
<span>  std.error <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="va">pi</span>, <span class="fu"><a href="https://rdrr.io/r/base/Log.html">exp</a></span><span class="op">(</span><span class="fl">1</span><span class="op">)</span>, <span class="fu"><a href="https://rdrr.io/r/base/MathFun.html">sqrt</a></span><span class="op">(</span><span class="fl">2</span><span class="op">)</span><span class="op">)</span><span class="op">)</span></span>
<span></span>
<span><span class="va">gl</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>  stat1 <span class="op">=</span> <span class="st">"blah"</span>,</span>
<span>  stat2 <span class="op">=</span> <span class="st">"blah blah"</span><span class="op">)</span></span>
<span></span>
<span><span class="va">mod</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html">list</a></span><span class="op">(</span></span>
<span>  tidy <span class="op">=</span> <span class="va">ti</span>,</span>
<span>  glance <span class="op">=</span> <span class="va">gl</span><span class="op">)</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/base/class.html">class</a></span><span class="op">(</span><span class="va">mod</span><span class="op">)</span> <span class="op">&lt;-</span> <span class="st">"modelsummary_list"</span></span>
<span></span>
<span><span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">mod</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_6g9581vmo5mt2pbh0v17(i, j, css_id) {
          var table = document.getElementById("tinytable_6g9581vmo5mt2pbh0v17");
          var cell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function spanCell_6g9581vmo5mt2pbh0v17(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_6g9581vmo5mt2pbh0v17");
        const targetCell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
        if (!targetCell) {
          console.warn(`Cell at (${i}, ${j}) not found.`);
        }

        // Get all cells that need to be removed
        const cellsToRemove = [];
        for (let r = 0; r < rowspan; r++) {
          for (let c = 0; c < colspan; c++) {
            if (r === 0 && c === 0) continue; // Skip the target cell
            const cell = table.querySelector(`[data-row="${i + r}"][data-col="${j + c}"]`);
            if (cell) {
              cellsToRemove.push(cell);
            }
          }
        }

        // Remove all cells
        cellsToRemove.forEach(cell => cell.remove());

        // Set rowspan and colspan of the target cell if it exists
        if (targetCell) {
          targetCell.rowSpan = rowspan;
          targetCell.colSpan = colspan;
        }
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: '8', j: 1 },  ], css_id: 'tinytable_css_c0y5zdu89hrbse4x3dky',}, 
          { positions: [ { i: '6', j: 1 },  ], css_id: 'tinytable_css_hj80xx7jr0aua3u8bzfx',}, 
          { positions: [ { i: '1', j: 1 }, { i: '2', j: 1 }, { i: '3', j: 1 }, { i: '4', j: 1 }, { i: '5', j: 1 }, { i: '7', j: 1 },  ], css_id: 'tinytable_css_ptqiqhm44l4amw8h52nh',}, 
          { positions: [ { i: '0', j: 1 },  ], css_id: 'tinytable_css_z9gfntkmhd6ztiisyxy8',}, 
          { positions: [ { i: '8', j: 0 },  ], css_id: 'tinytable_css_5p632vlnwkb025it8fwu',}, 
          { positions: [ { i: '6', j: 0 },  ], css_id: 'tinytable_css_s6u8r71hcu06sdceh74r',}, 
          { positions: [ { i: '1', j: 0 }, { i: '2', j: 0 }, { i: '3', j: 0 }, { i: '4', j: 0 }, { i: '5', j: 0 }, { i: '7', j: 0 },  ], css_id: 'tinytable_css_gn2q9pn0xf59a6j2hcl3',}, 
          { positions: [ { i: '0', j: 0 },  ], css_id: 'tinytable_css_mhzq6bswjkfv1y9w9e5c',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_6g9581vmo5mt2pbh0v17(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script><style>
      /* tinytable css entries after */
      .table td.tinytable_css_c0y5zdu89hrbse4x3dky, .table th.tinytable_css_c0y5zdu89hrbse4x3dky { text-align: center; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_hj80xx7jr0aua3u8bzfx, .table th.tinytable_css_hj80xx7jr0aua3u8bzfx { text-align: center; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_ptqiqhm44l4amw8h52nh, .table th.tinytable_css_ptqiqhm44l4amw8h52nh { text-align: center; }
      .table td.tinytable_css_z9gfntkmhd6ztiisyxy8, .table th.tinytable_css_z9gfntkmhd6ztiisyxy8 { text-align: center; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
      .table td.tinytable_css_5p632vlnwkb025it8fwu, .table th.tinytable_css_5p632vlnwkb025it8fwu { text-align: left; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_s6u8r71hcu06sdceh74r, .table th.tinytable_css_s6u8r71hcu06sdceh74r { text-align: left; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_gn2q9pn0xf59a6j2hcl3, .table th.tinytable_css_gn2q9pn0xf59a6j2hcl3 { text-align: left; }
      .table td.tinytable_css_mhzq6bswjkfv1y9w9e5c, .table th.tinytable_css_mhzq6bswjkfv1y9w9e5c { text-align: left; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
    </style>
<div class="container">
      <table class="table table-borderless" id="tinytable_6g9581vmo5mt2pbh0v17" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
<thead><tr>
<th scope="col" data-row="0" data-col="0"> </th>
                <th scope="col" data-row="0" data-col="1">(1)</th>
              </tr></thead>
<tbody>
<tr>
<td data-row="1" data-col="0">coef1</td>
                  <td data-row="1" data-col="1">1.000</td>
                </tr>
<tr>
<td data-row="2" data-col="0"></td>
                  <td data-row="2" data-col="1">(3.142)</td>
                </tr>
<tr>
<td data-row="3" data-col="0">coef2</td>
                  <td data-row="3" data-col="1">2.000</td>
                </tr>
<tr>
<td data-row="4" data-col="0"></td>
                  <td data-row="4" data-col="1">(2.718)</td>
                </tr>
<tr>
<td data-row="5" data-col="0">coef3</td>
                  <td data-row="5" data-col="1">3.000</td>
                </tr>
<tr>
<td data-row="6" data-col="0"></td>
                  <td data-row="6" data-col="1">(1.414)</td>
                </tr>
<tr>
<td data-row="7" data-col="0">stat1</td>
                  <td data-row="7" data-col="1">blah</td>
                </tr>
<tr>
<td data-row="8" data-col="0">stat2</td>
                  <td data-row="8" data-col="1">blah blah</td>
                </tr>
</tbody>
</table>
</div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
</section><section id="unsupported-models-glance-and-tidy" class="level1"><h1>Unsupported models: <code>glance</code> and <code>tidy</code>
</h1>
<p><code>modelsummary</code> relies on two functions from the <code>broom</code> package to extract model information: <code>tidy</code> and <code>glance</code>. If <code>broom</code> doesn’t support the type of model you are trying to summarize, <code>modelsummary</code> won’t support it out of the box. Thankfully, it is extremely easy to add support for most models using custom methods.</p>
<p>For example, models produced by the <code>MCMCglmm</code> package are not currently supported by <code>broom</code>. To add support, you simply need to create a <code>tidy</code> and a <code>glance</code> method:</p>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="co"># load packages and data</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="va"><a href="https://modelsummary.com">modelsummary</a></span><span class="op">)</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="va"><a href="https://github.com/jarrodhadfield/MCMCglmm">MCMCglmm</a></span><span class="op">)</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/utils/data.html">data</a></span><span class="op">(</span><span class="va">PlodiaPO</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># add custom functions to extract estimates (tidy) and goodness-of-fit (glance) information</span></span>
<span><span class="va">tidy.MCMCglmm</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>    <span class="va">s</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/summary.html">summary</a></span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span></span>
<span>    <span class="va">ret</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>      term      <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/row.names.html">row.names</a></span><span class="op">(</span><span class="va">s</span><span class="op">$</span><span class="va">solutions</span><span class="op">)</span>,</span>
<span>      estimate  <span class="op">=</span> <span class="va">s</span><span class="op">$</span><span class="va">solutions</span><span class="op">[</span>, <span class="fl">1</span><span class="op">]</span>,</span>
<span>      conf.low  <span class="op">=</span> <span class="va">s</span><span class="op">$</span><span class="va">solutions</span><span class="op">[</span>, <span class="fl">2</span><span class="op">]</span>,</span>
<span>      conf.high <span class="op">=</span> <span class="va">s</span><span class="op">$</span><span class="va">solutions</span><span class="op">[</span>, <span class="fl">3</span><span class="op">]</span><span class="op">)</span></span>
<span>    <span class="va">ret</span></span>
<span><span class="op">}</span></span>
<span></span>
<span><span class="va">glance.MCMCglmm</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>    <span class="va">ret</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>      dic <span class="op">=</span> <span class="va">x</span><span class="op">$</span><span class="va">DIC</span>,</span>
<span>      n   <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/nrow.html">nrow</a></span><span class="op">(</span><span class="va">x</span><span class="op">$</span><span class="va">X</span><span class="op">)</span><span class="op">)</span></span>
<span>    <span class="va">ret</span></span>
<span><span class="op">}</span></span>
<span></span>
<span><span class="co"># estimate a simple model</span></span>
<span><span class="va">model</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/pkg/MCMCglmm/man/MCMCglmm.html">MCMCglmm</a></span><span class="op">(</span><span class="va">PO</span> <span class="op">~</span> <span class="fl">1</span> <span class="op">+</span> <span class="va">plate</span>, random <span class="op">=</span> <span class="op">~</span> <span class="va">FSfamily</span>, data <span class="op">=</span> <span class="va">PlodiaPO</span>, verbose<span class="op">=</span><span class="cn">FALSE</span>, pr<span class="op">=</span><span class="cn">TRUE</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># summarize the model</span></span>
<span><span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">model</span>, statistic <span class="op">=</span> <span class="st">'conf.int'</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<p>Three important things to note.</p>
<p>First, the methods are named <code>tidy.MCMCglmm</code> and <code>glance.MCMCglmm</code> because the model object I am trying to summarize is of class <code>MCMCglmm</code>. You can find the class of a model by running: <code>class(model)</code>.</p>
<p>Second, both of the methods include the ellipsis <code>...</code> argument.</p>
<p>Third, in the example above we used the <code>statistic = 'conf.int'</code> argument. This is because the <code>tidy</code> method produces <code>conf.low</code> and <code>conf.high</code> columns. In most cases, users will define <code>std.error</code> column in their custom <code>tidy</code> methods, so the <code>statistic</code> argument will need to be adjusted.</p>
<p>If you create new <code>tidy</code> and <code>glance</code> methods, please consider contributing them to <code>broom</code> so that the rest of the community can benefit from your work: https://github.com/tidymodels/broom</p>
</section><section id="modifying-information-tidy_custom-and-glance_custom" class="level1"><h1>Modifying information: <code>tidy_custom</code> and <code>glance_custom</code>
</h1>
<p>Users may want to include more information than is made available by the default extractor function. For example, models produced by the <code><a href="https://rdrr.io/pkg/MASS/man/polr.html">MASS::polr</a></code> do not produce p values by default, which means that we cannot use the <code>stars=TRUE</code> argument in <code>modelsummary</code>. However, it is possible to extract this information by using the <code><a href="https://rdrr.io/pkg/lmtest/man/coeftest.html">lmtest::coeftest</a></code> function. To include such custom information, we will define new <code>glance_custom</code> and <code>tidy_custom</code> methods.</p>
<p>We begin by estimating a model with the <code><a href="https://rdrr.io/pkg/MASS/man/polr.html">MASS::polr</a></code>:</p>
<div class="cell">
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="va"><a href="http://www.stats.ox.ac.uk/pub/MASS4/">MASS</a></span><span class="op">)</span></span>
<span></span>
<span><span class="va">mod_ordinal</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/pkg/MASS/man/polr.html">polr</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/factor.html">as.ordered</a></span><span class="op">(</span><span class="va">gear</span><span class="op">)</span> <span class="op">~</span> <span class="va">mpg</span> <span class="op">+</span> <span class="va">drat</span>, data <span class="op">=</span> <span class="va">mtcars</span><span class="op">)</span></span>
<span></span>
<span><span class="fu"><a href="https://modelsummary.com/man/get_estimates.html">get_estimates</a></span><span class="op">(</span><span class="va">mod_ordinal</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stderr">
<pre><code>
Re-fitting to get Hessian</code></pre>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>  term     estimate  std.error conf.level   conf.low  conf.high  statistic df.error      p.value component s.value group
1  3|4 13.962948762 4.04107299       0.95  5.6851860 22.2407115  3.4552578       28 0.0017706302     alpha     9.1      
2  4|5 16.898937339 4.39497069       0.95  7.8962480 25.9016267  3.8450626       28 0.0006356348     alpha    10.6      
3  mpg -0.008646679 0.09034201       0.95 -0.1916706  0.1708667 -0.0957105       28 0.9244322337      beta     0.1      
4 drat  3.949431922 1.30665144       0.95  1.6191505  6.8457246  3.0225597       28 0.0053120619      beta     7.6      </code></pre>
</div>
</div>
<p>The <code>get_estimates</code> function shows that our default extractor does <em>not</em> produce a <code>p.value</code> column. As a result, setting <code>stars=TRUE</code> in <code>modelsummary</code> will produce an error.</p>
<p>We know that the <code><a href="https://rdrr.io/pkg/MASS/man/polr.html">MASS::polr</a></code> produces an object of class <code>polr</code>:</p>
<div class="cell">
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/class.html">class</a></span><span class="op">(</span><span class="va">mod_ordinal</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "polr"</code></pre>
</div>
</div>
<p>To extract more (custom) information from a model of this class, we thus define a method called <code>tidy_custom.polr</code> which returns a data.frame with two columns: <code>term</code> and <code>p.value</code>:</p>
<div class="cell">
<div class="sourceCode" id="cb9"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">tidy_custom.polr</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>  <span class="va">s</span> <span class="op">&lt;-</span> <span class="fu">lmtest</span><span class="fu">::</span><span class="fu"><a href="https://rdrr.io/pkg/lmtest/man/coeftest.html">coeftest</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span></span>
<span>  <span class="va">out</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>    term <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/row.names.html">row.names</a></span><span class="op">(</span><span class="va">s</span><span class="op">)</span>,</span>
<span>    p.value <span class="op">=</span> <span class="va">s</span><span class="op">[</span>, <span class="st">"Pr(&gt;|t|)"</span><span class="op">]</span><span class="op">)</span></span>
<span>  <span class="va">out</span></span>
<span><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>When this method is defined, <code>modelsummary</code> can automatically extract p values from all models of this class, and will now work properly with <code>stars=TRUE</code>:</p>
<div class="cell">
<div class="sourceCode" id="cb10"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">mod_ordinal</span>, stars <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_mz1hxjex0ueczwy7vavv(i, j, css_id) {
          var table = document.getElementById("tinytable_mz1hxjex0ueczwy7vavv");
          var cell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function spanCell_mz1hxjex0ueczwy7vavv(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_mz1hxjex0ueczwy7vavv");
        const targetCell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
        if (!targetCell) {
          console.warn(`Cell at (${i}, ${j}) not found.`);
        }

        // Get all cells that need to be removed
        const cellsToRemove = [];
        for (let r = 0; r < rowspan; r++) {
          for (let c = 0; c < colspan; c++) {
            if (r === 0 && c === 0) continue; // Skip the target cell
            const cell = table.querySelector(`[data-row="${i + r}"][data-col="${j + c}"]`);
            if (cell) {
              cellsToRemove.push(cell);
            }
          }
        }

        // Remove all cells
        cellsToRemove.forEach(cell => cell.remove());

        // Set rowspan and colspan of the target cell if it exists
        if (targetCell) {
          targetCell.rowSpan = rowspan;
          targetCell.colSpan = colspan;
        }
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: '12', j: 1 },  ], css_id: 'tinytable_css_7da113cze0veopm6nnr1',}, 
          { positions: [ { i: '8', j: 1 },  ], css_id: 'tinytable_css_q6civmi5c8ba9mbmso0f',}, 
          { positions: [ { i: '1', j: 1 }, { i: '2', j: 1 }, { i: '3', j: 1 }, { i: '4', j: 1 }, { i: '5', j: 1 }, { i: '6', j: 1 }, { i: '7', j: 1 }, { i: '9', j: 1 }, { i: '10', j: 1 }, { i: '11', j: 1 },  ], css_id: 'tinytable_css_w37jof44pigk7jse6l35',}, 
          { positions: [ { i: '0', j: 1 },  ], css_id: 'tinytable_css_emm71l0k07b2qxy23or6',}, 
          { positions: [ { i: '12', j: 0 },  ], css_id: 'tinytable_css_mlxchr78exwunyf6qr4e',}, 
          { positions: [ { i: '8', j: 0 },  ], css_id: 'tinytable_css_nhfa1uei6hy8nk573z28',}, 
          { positions: [ { i: '1', j: 0 }, { i: '2', j: 0 }, { i: '3', j: 0 }, { i: '4', j: 0 }, { i: '5', j: 0 }, { i: '6', j: 0 }, { i: '7', j: 0 }, { i: '9', j: 0 }, { i: '10', j: 0 }, { i: '11', j: 0 },  ], css_id: 'tinytable_css_sijufg0twzpdiv2j5qiu',}, 
          { positions: [ { i: '0', j: 0 },  ], css_id: 'tinytable_css_vwjglutih6t0u3y7q0m7',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_mz1hxjex0ueczwy7vavv(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script><style>
      /* tinytable css entries after */
      .table td.tinytable_css_7da113cze0veopm6nnr1, .table th.tinytable_css_7da113cze0veopm6nnr1 { text-align: center; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_q6civmi5c8ba9mbmso0f, .table th.tinytable_css_q6civmi5c8ba9mbmso0f { text-align: center; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_w37jof44pigk7jse6l35, .table th.tinytable_css_w37jof44pigk7jse6l35 { text-align: center; }
      .table td.tinytable_css_emm71l0k07b2qxy23or6, .table th.tinytable_css_emm71l0k07b2qxy23or6 { text-align: center; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
      .table td.tinytable_css_mlxchr78exwunyf6qr4e, .table th.tinytable_css_mlxchr78exwunyf6qr4e { text-align: left; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_nhfa1uei6hy8nk573z28, .table th.tinytable_css_nhfa1uei6hy8nk573z28 { text-align: left; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_sijufg0twzpdiv2j5qiu, .table th.tinytable_css_sijufg0twzpdiv2j5qiu { text-align: left; }
      .table td.tinytable_css_vwjglutih6t0u3y7q0m7, .table th.tinytable_css_vwjglutih6t0u3y7q0m7 { text-align: left; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
    </style>
<div class="container">
      <table class="table table-borderless" id="tinytable_mz1hxjex0ueczwy7vavv" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
<thead><tr>
<th scope="col" data-row="0" data-col="0"> </th>
                <th scope="col" data-row="0" data-col="1">(1)</th>
              </tr></thead>
<tfoot><tr><td colspan="2">+ p </td></tr></tfoot>
<tbody>
<tr>
<td data-row="1" data-col="0">3|4</td>
                  <td data-row="1" data-col="1">13.963**</td>
                </tr>
<tr>
<td data-row="2" data-col="0"></td>
                  <td data-row="2" data-col="1">(4.041)</td>
                </tr>
<tr>
<td data-row="3" data-col="0">4|5</td>
                  <td data-row="3" data-col="1">16.899***</td>
                </tr>
<tr>
<td data-row="4" data-col="0"></td>
                  <td data-row="4" data-col="1">(4.395)</td>
                </tr>
<tr>
<td data-row="5" data-col="0">mpg</td>
                  <td data-row="5" data-col="1">-0.009</td>
                </tr>
<tr>
<td data-row="6" data-col="0"></td>
                  <td data-row="6" data-col="1">(0.090)</td>
                </tr>
<tr>
<td data-row="7" data-col="0">drat</td>
                  <td data-row="7" data-col="1">3.949**</td>
                </tr>
<tr>
<td data-row="8" data-col="0"></td>
                  <td data-row="8" data-col="1">(1.307)</td>
                </tr>
<tr>
<td data-row="9" data-col="0">Num.Obs.</td>
                  <td data-row="9" data-col="1">32</td>
                </tr>
<tr>
<td data-row="10" data-col="0">AIC</td>
                  <td data-row="10" data-col="1">51.1</td>
                </tr>
<tr>
<td data-row="11" data-col="0">BIC</td>
                  <td data-row="11" data-col="1">57.0</td>
                </tr>
<tr>
<td data-row="12" data-col="0">RMSE</td>
                  <td data-row="12" data-col="1">3.44</td>
                </tr>
</tbody>
</table>
</div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
</section><section id="new-information-tidy_custom-and-glance_custom" class="level1"><h1>New information: <code>tidy_custom</code> and <code>glance_custom</code>
</h1>
<p>Sometimes users will want to include information that is not supplied by those functions. A pretty easy way to include extra information is to define new <code>glance_custom</code> and <code>tidy_custom</code> methods. To illustrate, we estimate two linear regression models using the <code>lm</code> function:</p>
<div class="cell">
<div class="sourceCode" id="cb11"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="va"><a href="https://modelsummary.com">modelsummary</a></span><span class="op">)</span></span>
<span></span>
<span><span class="va">mod</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html">list</a></span><span class="op">(</span><span class="op">)</span></span>
<span><span class="va">mod</span><span class="op">[[</span><span class="fl">1</span><span class="op">]</span><span class="op">]</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/stats/lm.html">lm</a></span><span class="op">(</span><span class="va">hp</span> <span class="op">~</span> <span class="va">mpg</span> <span class="op">+</span> <span class="va">drat</span>, <span class="va">mtcars</span><span class="op">)</span></span>
<span><span class="va">mod</span><span class="op">[[</span><span class="fl">2</span><span class="op">]</span><span class="op">]</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/stats/lm.html">lm</a></span><span class="op">(</span><span class="va">wt</span> <span class="op">~</span> <span class="va">mpg</span> <span class="op">+</span> <span class="va">drat</span> <span class="op">+</span> <span class="va">am</span>, <span class="va">mtcars</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>In <code>R</code>, the <code>lm</code> function produces models of class “lm”:</p>
<div class="cell">
<div class="sourceCode" id="cb12"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/class.html">class</a></span><span class="op">(</span><span class="va">mod</span><span class="op">[[</span><span class="fl">1</span><span class="op">]</span><span class="op">]</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "lm"</code></pre>
</div>
</div>
<p>Let’s say you would like to print the dependent variable for each model of this particular class. All you need to do is define a new method called <code>glance_custom.lm</code>. This method should return a data.frame (or tibble) with 1 row, and 1 column per piece of information you want to display. For example:</p>
<div class="cell">
<div class="sourceCode" id="cb14"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">glance_custom.lm</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>    <span class="va">dv</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/character.html">as.character</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/stats/formula.html">formula</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span><span class="op">[</span><span class="fl">2</span><span class="op">]</span><span class="op">)</span></span>
<span>    <span class="va">out</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span><span class="st">"DV"</span> <span class="op">=</span> <span class="va">dv</span><span class="op">)</span></span>
<span>    <span class="kw"><a href="https://rdrr.io/r/base/function.html">return</a></span><span class="op">(</span><span class="va">out</span><span class="op">)</span></span>
<span><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Now, let’s customize the body of the table. The <code>vcov</code> argument already allows users to customize uncertainty estimates. But imagine you want to override the <em>coefficient estimates</em> of your “lm” models. Easy! All you need to do is define a <code>tidy_custom.lm</code> method which returns a data.frame (or tibble) with one column called “term” and one column called “estimate”.</p>
<p>Here, we’ll substitute estimates by an up/down-pointing triangles which represents their signs:</p>
<div class="cell">
<div class="sourceCode" id="cb15"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">tidy_custom.lm</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>    <span class="va">s</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/summary.html">summary</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span><span class="op">$</span><span class="va">coefficients</span></span>
<span>    <span class="va">out</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>      term <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/row.names.html">row.names</a></span><span class="op">(</span><span class="va">s</span><span class="op">)</span>,</span>
<span>      estimate <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/ifelse.html">ifelse</a></span><span class="op">(</span><span class="va">s</span><span class="op">[</span>,<span class="fl">1</span><span class="op">]</span> <span class="op">&gt;</span> <span class="fl">0</span>, <span class="st">'▲'</span>, <span class="st">'▼'</span><span class="op">)</span><span class="op">)</span></span>
<span>    <span class="kw"><a href="https://rdrr.io/r/base/function.html">return</a></span><span class="op">(</span><span class="va">out</span><span class="op">)</span></span>
<span><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>After you define the <code>glance_custom</code> and <code>tidy_custom</code> methods, <code>modelsummary</code> will automatically display your customized model information:</p>
<div class="cell">
<div class="sourceCode" id="cb16"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">mod</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_51ljs4hgbbcaoqtucq5h(i, j, css_id) {
          var table = document.getElementById("tinytable_51ljs4hgbbcaoqtucq5h");
          var cell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function spanCell_51ljs4hgbbcaoqtucq5h(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_51ljs4hgbbcaoqtucq5h");
        const targetCell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
        if (!targetCell) {
          console.warn(`Cell at (${i}, ${j}) not found.`);
        }

        // Get all cells that need to be removed
        const cellsToRemove = [];
        for (let r = 0; r < rowspan; r++) {
          for (let c = 0; c < colspan; c++) {
            if (r === 0 && c === 0) continue; // Skip the target cell
            const cell = table.querySelector(`[data-row="${i + r}"][data-col="${j + c}"]`);
            if (cell) {
              cellsToRemove.push(cell);
            }
          }
        }

        // Remove all cells
        cellsToRemove.forEach(cell => cell.remove());

        // Set rowspan and colspan of the target cell if it exists
        if (targetCell) {
          targetCell.rowSpan = rowspan;
          targetCell.colSpan = colspan;
        }
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: '17', j: 1 }, { i: '17', j: 2 },  ], css_id: 'tinytable_css_sl80n3c0cg1ivdel48br',}, 
          { positions: [ { i: '8', j: 2 }, { i: '8', j: 1 },  ], css_id: 'tinytable_css_i06dmrw7ydw8uuiriusr',}, 
          { positions: [ { i: '2', j: 1 }, { i: '3', j: 1 }, { i: '4', j: 1 }, { i: '1', j: 1 }, { i: '6', j: 1 }, { i: '7', j: 1 }, { i: '3', j: 2 }, { i: '9', j: 1 }, { i: '10', j: 1 }, { i: '11', j: 1 }, { i: '12', j: 1 }, { i: '13', j: 1 }, { i: '14', j: 1 }, { i: '15', j: 1 }, { i: '16', j: 1 }, { i: '12', j: 2 }, { i: '5', j: 1 }, { i: '1', j: 2 }, { i: '2', j: 2 }, { i: '16', j: 2 }, { i: '4', j: 2 }, { i: '5', j: 2 }, { i: '6', j: 2 }, { i: '7', j: 2 }, { i: '9', j: 2 }, { i: '10', j: 2 }, { i: '11', j: 2 }, { i: '13', j: 2 }, { i: '14', j: 2 }, { i: '15', j: 2 },  ], css_id: 'tinytable_css_gy6yeuajp8ywv68ephrm',}, 
          { positions: [ { i: '0', j: 1 }, { i: '0', j: 2 },  ], css_id: 'tinytable_css_oy3hefkhmc3wyro5nt58',}, 
          { positions: [ { i: '17', j: 0 },  ], css_id: 'tinytable_css_jxp51u7rcap9qcf7a85c',}, 
          { positions: [ { i: '8', j: 0 },  ], css_id: 'tinytable_css_irgs8170dxxacwi2vt91',}, 
          { positions: [ { i: '1', j: 0 }, { i: '2', j: 0 }, { i: '3', j: 0 }, { i: '4', j: 0 }, { i: '5', j: 0 }, { i: '6', j: 0 }, { i: '7', j: 0 }, { i: '12', j: 0 }, { i: '9', j: 0 }, { i: '10', j: 0 }, { i: '11', j: 0 }, { i: '16', j: 0 }, { i: '13', j: 0 }, { i: '14', j: 0 }, { i: '15', j: 0 },  ], css_id: 'tinytable_css_k6ro0s9wh2crnxivhfx3',}, 
          { positions: [ { i: '0', j: 0 },  ], css_id: 'tinytable_css_1vd3up6w0flkn1ov0zto',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_51ljs4hgbbcaoqtucq5h(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script><style>
      /* tinytable css entries after */
      .table td.tinytable_css_sl80n3c0cg1ivdel48br, .table th.tinytable_css_sl80n3c0cg1ivdel48br { text-align: center; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_i06dmrw7ydw8uuiriusr, .table th.tinytable_css_i06dmrw7ydw8uuiriusr { text-align: center; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_gy6yeuajp8ywv68ephrm, .table th.tinytable_css_gy6yeuajp8ywv68ephrm { text-align: center; }
      .table td.tinytable_css_oy3hefkhmc3wyro5nt58, .table th.tinytable_css_oy3hefkhmc3wyro5nt58 { text-align: center; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
      .table td.tinytable_css_jxp51u7rcap9qcf7a85c, .table th.tinytable_css_jxp51u7rcap9qcf7a85c { text-align: left; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_irgs8170dxxacwi2vt91, .table th.tinytable_css_irgs8170dxxacwi2vt91 { text-align: left; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_k6ro0s9wh2crnxivhfx3, .table th.tinytable_css_k6ro0s9wh2crnxivhfx3 { text-align: left; }
      .table td.tinytable_css_1vd3up6w0flkn1ov0zto, .table th.tinytable_css_1vd3up6w0flkn1ov0zto { text-align: left; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
    </style>
<div class="container">
      <table class="table table-borderless" id="tinytable_51ljs4hgbbcaoqtucq5h" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
<thead><tr>
<th scope="col" data-row="0" data-col="0"> </th>
                <th scope="col" data-row="0" data-col="1">(1)</th>
                <th scope="col" data-row="0" data-col="2">(2)</th>
              </tr></thead>
<tbody>
<tr>
<td data-row="1" data-col="0">(Intercept)</td>
                  <td data-row="1" data-col="1">▲</td>
                  <td data-row="1" data-col="2">▲</td>
                </tr>
<tr>
<td data-row="2" data-col="0"></td>
                  <td data-row="2" data-col="1">(55.415)</td>
                  <td data-row="2" data-col="2">(0.728)</td>
                </tr>
<tr>
<td data-row="3" data-col="0">mpg</td>
                  <td data-row="3" data-col="1">▼</td>
                  <td data-row="3" data-col="2">▼</td>
                </tr>
<tr>
<td data-row="4" data-col="0"></td>
                  <td data-row="4" data-col="1">(1.792)</td>
                  <td data-row="4" data-col="2">(0.019)</td>
                </tr>
<tr>
<td data-row="5" data-col="0">drat</td>
                  <td data-row="5" data-col="1">▲</td>
                  <td data-row="5" data-col="2">▼</td>
                </tr>
<tr>
<td data-row="6" data-col="0"></td>
                  <td data-row="6" data-col="1">(20.198)</td>
                  <td data-row="6" data-col="2">(0.245)</td>
                </tr>
<tr>
<td data-row="7" data-col="0">am</td>
                  <td data-row="7" data-col="1"></td>
                  <td data-row="7" data-col="2">▼</td>
                </tr>
<tr>
<td data-row="8" data-col="0"></td>
                  <td data-row="8" data-col="1"></td>
                  <td data-row="8" data-col="2">(0.240)</td>
                </tr>
<tr>
<td data-row="9" data-col="0">Num.Obs.</td>
                  <td data-row="9" data-col="1">32</td>
                  <td data-row="9" data-col="2">32</td>
                </tr>
<tr>
<td data-row="10" data-col="0">R2</td>
                  <td data-row="10" data-col="1">0.614</td>
                  <td data-row="10" data-col="2">0.803</td>
                </tr>
<tr>
<td data-row="11" data-col="0">R2 Adj.</td>
                  <td data-row="11" data-col="1">0.588</td>
                  <td data-row="11" data-col="2">0.782</td>
                </tr>
<tr>
<td data-row="12" data-col="0">AIC</td>
                  <td data-row="12" data-col="1">337.9</td>
                  <td data-row="12" data-col="2">46.4</td>
                </tr>
<tr>
<td data-row="13" data-col="0">BIC</td>
                  <td data-row="13" data-col="1">343.7</td>
                  <td data-row="13" data-col="2">53.7</td>
                </tr>
<tr>
<td data-row="14" data-col="0">Log.Lik.</td>
                  <td data-row="14" data-col="1">-164.940</td>
                  <td data-row="14" data-col="2">-18.201</td>
                </tr>
<tr>
<td data-row="15" data-col="0">F</td>
                  <td data-row="15" data-col="1">23.100</td>
                  <td data-row="15" data-col="2">38.066</td>
                </tr>
<tr>
<td data-row="16" data-col="0">RMSE</td>
                  <td data-row="16" data-col="1">41.91</td>
                  <td data-row="16" data-col="2">0.43</td>
                </tr>
<tr>
<td data-row="17" data-col="0">DV</td>
                  <td data-row="17" data-col="1">hp</td>
                  <td data-row="17" data-col="2">wt</td>
                </tr>
</tbody>
</table>
</div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
<p>Note that you can define a <code>std.error</code> column in <code>tidy_custom.lm</code> to replace the uncertainty estimates instead of the coefficients.</p>
</section><section id="customization-new-model-class" class="level1"><h1>Customization: New model class</h1>
<p>An even more fundamental way to customize the output would be to completely bypass <code>modelsummary</code>’s extractor functions by assigning a new class name to your model. For example,</p>
<div class="cell">
<div class="sourceCode" id="cb17"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="co"># estimate a linear model</span></span>
<span><span class="va">mod_custom</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/stats/lm.html">lm</a></span><span class="op">(</span><span class="va">hp</span> <span class="op">~</span> <span class="va">mpg</span> <span class="op">+</span> <span class="va">drat</span>, <span class="va">mtcars</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># assign it a new class</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/base/class.html">class</a></span><span class="op">(</span><span class="va">mod_custom</span><span class="op">)</span> <span class="op">&lt;-</span> <span class="st">"custom"</span></span>
<span></span>
<span><span class="co"># define tidy and glance methods</span></span>
<span><span class="va">tidy.custom</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>  <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>    term <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/names.html">names</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/stats/coef.html">coef</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span><span class="op">)</span>,</span>
<span>    estimate <span class="op">=</span> <span class="va">letters</span><span class="op">[</span><span class="fl">1</span><span class="op">:</span><span class="fu"><a href="https://rdrr.io/r/base/length.html">length</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/stats/coef.html">coef</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span><span class="op">)</span><span class="op">]</span>,</span>
<span>    std.error <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/seq.html">seq_along</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/stats/coef.html">coef</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span><span class="op">)</span></span>
<span>  <span class="op">)</span></span>
<span><span class="op">}</span></span>
<span></span>
<span><span class="va">glance.custom</span> <span class="op">&lt;-</span> <span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">...</span><span class="op">)</span> <span class="op">{</span></span>
<span>  <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html">data.frame</a></span><span class="op">(</span></span>
<span>    <span class="st">"Model"</span> <span class="op">=</span> <span class="st">"Custom"</span>,</span>
<span>    <span class="st">"nobs"</span> <span class="op">=</span> <span class="fu">stats</span><span class="fu">:::</span><span class="fu">nobs.lm</span><span class="op">(</span><span class="va">x</span><span class="op">)</span></span>
<span>  <span class="op">)</span></span>
<span><span class="op">}</span></span>
<span></span>
<span><span class="co"># summarize</span></span>
<span><span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">mod_custom</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_nulj3l40h7t8n5ndu1u0(i, j, css_id) {
          var table = document.getElementById("tinytable_nulj3l40h7t8n5ndu1u0");
          var cell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function spanCell_nulj3l40h7t8n5ndu1u0(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_nulj3l40h7t8n5ndu1u0");
        const targetCell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
        if (!targetCell) {
          console.warn(`Cell at (${i}, ${j}) not found.`);
        }

        // Get all cells that need to be removed
        const cellsToRemove = [];
        for (let r = 0; r < rowspan; r++) {
          for (let c = 0; c < colspan; c++) {
            if (r === 0 && c === 0) continue; // Skip the target cell
            const cell = table.querySelector(`[data-row="${i + r}"][data-col="${j + c}"]`);
            if (cell) {
              cellsToRemove.push(cell);
            }
          }
        }

        // Remove all cells
        cellsToRemove.forEach(cell => cell.remove());

        // Set rowspan and colspan of the target cell if it exists
        if (targetCell) {
          targetCell.rowSpan = rowspan;
          targetCell.colSpan = colspan;
        }
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: '8', j: 1 },  ], css_id: 'tinytable_css_mtxblbu5elynplv3zeaa',}, 
          { positions: [ { i: '6', j: 1 },  ], css_id: 'tinytable_css_pzvury41tt3eievljcyc',}, 
          { positions: [ { i: '1', j: 1 }, { i: '2', j: 1 }, { i: '3', j: 1 }, { i: '4', j: 1 }, { i: '5', j: 1 }, { i: '7', j: 1 },  ], css_id: 'tinytable_css_mev8ip09ew4jsl5y708f',}, 
          { positions: [ { i: '0', j: 1 },  ], css_id: 'tinytable_css_k9wjr341emtxnsn2um4w',}, 
          { positions: [ { i: '8', j: 0 },  ], css_id: 'tinytable_css_y2lz51s4zdsazo5fy448',}, 
          { positions: [ { i: '6', j: 0 },  ], css_id: 'tinytable_css_grim5fqi8bes72uqrct8',}, 
          { positions: [ { i: '1', j: 0 }, { i: '2', j: 0 }, { i: '3', j: 0 }, { i: '4', j: 0 }, { i: '5', j: 0 }, { i: '7', j: 0 },  ], css_id: 'tinytable_css_ggv51ax4c2xsv9inp394',}, 
          { positions: [ { i: '0', j: 0 },  ], css_id: 'tinytable_css_2itvu9mdtit4fweah2p9',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_nulj3l40h7t8n5ndu1u0(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script><style>
      /* tinytable css entries after */
      .table td.tinytable_css_mtxblbu5elynplv3zeaa, .table th.tinytable_css_mtxblbu5elynplv3zeaa { text-align: center; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_pzvury41tt3eievljcyc, .table th.tinytable_css_pzvury41tt3eievljcyc { text-align: center; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_mev8ip09ew4jsl5y708f, .table th.tinytable_css_mev8ip09ew4jsl5y708f { text-align: center; }
      .table td.tinytable_css_k9wjr341emtxnsn2um4w, .table th.tinytable_css_k9wjr341emtxnsn2um4w { text-align: center; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
      .table td.tinytable_css_y2lz51s4zdsazo5fy448, .table th.tinytable_css_y2lz51s4zdsazo5fy448 { text-align: left; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_grim5fqi8bes72uqrct8, .table th.tinytable_css_grim5fqi8bes72uqrct8 { text-align: left; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_ggv51ax4c2xsv9inp394, .table th.tinytable_css_ggv51ax4c2xsv9inp394 { text-align: left; }
      .table td.tinytable_css_2itvu9mdtit4fweah2p9, .table th.tinytable_css_2itvu9mdtit4fweah2p9 { text-align: left; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
    </style>
<div class="container">
      <table class="table table-borderless" id="tinytable_nulj3l40h7t8n5ndu1u0" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
<thead><tr>
<th scope="col" data-row="0" data-col="0"> </th>
                <th scope="col" data-row="0" data-col="1">(1)</th>
              </tr></thead>
<tbody>
<tr>
<td data-row="1" data-col="0">(Intercept)</td>
                  <td data-row="1" data-col="1">a</td>
                </tr>
<tr>
<td data-row="2" data-col="0"></td>
                  <td data-row="2" data-col="1">(1.000)</td>
                </tr>
<tr>
<td data-row="3" data-col="0">mpg</td>
                  <td data-row="3" data-col="1">b</td>
                </tr>
<tr>
<td data-row="4" data-col="0"></td>
                  <td data-row="4" data-col="1">(2.000)</td>
                </tr>
<tr>
<td data-row="5" data-col="0">drat</td>
                  <td data-row="5" data-col="1">c</td>
                </tr>
<tr>
<td data-row="6" data-col="0"></td>
                  <td data-row="6" data-col="1">(3.000)</td>
                </tr>
<tr>
<td data-row="7" data-col="0">Num.Obs.</td>
                  <td data-row="7" data-col="1">32</td>
                </tr>
<tr>
<td data-row="8" data-col="0">Model</td>
                  <td data-row="8" data-col="1">Custom</td>
                </tr>
</tbody>
</table>
</div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>
<p>Warning: When defining new <code>tidy</code> and <code>glance</code> methods, it is important to include an ellipsis argument (<code>...</code>).</p>
<p>Note that in the <code>glance.custom()</code> method, we called <code>stats:::nobs.lm()</code> instead of the default <code><a href="https://rdrr.io/r/stats/nobs.html">stats::nobs()</a></code> method, because the latter know does not know where to dispatch models of our new “custom” class. Being more explicit solves the problem.</p>
<p>An alternative would be to set a new class that inherits from the previous one, and to use a global option to set <code>broom</code> as the default extractor function (otherwise <code>modelsummary</code> will use its standard <code>lm</code> extractors by inheritance):</p>
<div class="cell">
<div class="sourceCode" id="cb18"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/options.html">options</a></span><span class="op">(</span>modelsummary_get <span class="op">=</span> <span class="st">"broom"</span><span class="op">)</span></span>
<span><span class="fu"><a href="https://rdrr.io/r/base/class.html">class</a></span><span class="op">(</span><span class="va">mod_custom</span><span class="op">)</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="st">"custom"</span>, <span class="st">"lm"</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
</section><section id="customization-modelsummary_list" class="level1"><h1>Customization: <code>modelsummary_list</code>
</h1>
<p>Another flexible way to customize model output is to use <code>output = "modelsummary_list"</code>. With this output option, <code><a href="https://modelsummary.com/man/modelsummary.html">modelsummary()</a></code> returns a list with two elements: <code>tidy</code> contains parameter estimates, standard errors, etc., and <code>glance</code> contains model statistics such as the AIC. For example,</p>
<div class="cell">
<div class="sourceCode" id="cb19"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">mod</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/stats/lm.html">lm</a></span><span class="op">(</span><span class="va">hp</span> <span class="op">~</span> <span class="va">mpg</span> <span class="op">+</span> <span class="va">drat</span>, <span class="va">mtcars</span><span class="op">)</span></span>
<span><span class="va">mod_list</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">mod</span>, output <span class="op">=</span> <span class="st">"modelsummary_list"</span><span class="op">)</span></span>
<span><span class="va">mod_list</span><span class="op">$</span><span class="va">tidy</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>         term   estimate std.error  statistic df.error      p.value s.value group conf.low conf.high
1 (Intercept) 278.515455 55.414866  5.0260061       29 2.359726e-05    15.4             NA        NA
2         mpg  -9.985499  1.791837 -5.5727709       29 5.172030e-06    17.6             NA        NA
3        drat  19.125752 20.197756  0.9469246       29 3.515013e-01     1.5             NA        NA</code></pre>
</div>
<div class="sourceCode" id="cb21"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">mod_list</span><span class="op">$</span><span class="va">glance</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>       aic      bic r.squared adj.r.squared     rmse nobs        F    logLik
1 337.8809 343.7438 0.6143611     0.5877653 41.90687   32 23.09994 -164.9404</code></pre>
</div>
</div>
<p>Both <code>tidy</code> and <code>glance</code> can now be customized, and the updated model can be passed back to modelsummary using <code>modelsummary(mod_list)</code>. All information that is displayed in the table is contained in <code>mod_list</code>, so this pattern allows for very flexible adjustments of output tables.</p>
<p>A useful example for this pattern concerns mixed models using <code>lme4</code>. Assume we want to compare the effect of using different degrees-of-freedom adjustments on the significance of the coefficients. The models have identical parameter estimates, standard errors, and model fit statistics - we only want to change the p-values. We use the <code>parameters</code> package to compute the adjusted p-values.</p>
<div class="cell">
<div class="sourceCode" id="cb23"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html">library</a></span><span class="op">(</span><span class="st"><a href="https://github.com/lme4/lme4/">"lme4"</a></span><span class="op">)</span></span>
<span><span class="va">mod</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/pkg/lme4/man/lmer.html">lmer</a></span><span class="op">(</span><span class="va">mpg</span> <span class="op">~</span> <span class="va">drat</span> <span class="op">+</span> <span class="op">(</span><span class="fl">1</span> <span class="op">|</span> <span class="va">am</span><span class="op">)</span>, data <span class="op">=</span> <span class="va">mtcars</span><span class="op">)</span></span>
<span><span class="va">mod_list</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="va">mod</span>, output <span class="op">=</span> <span class="st">"modelsummary_list"</span>, effects <span class="op">=</span> <span class="st">"fixed"</span><span class="op">)</span></span>
<span><span class="co"># create a copy, where we'll change the p-values</span></span>
<span><span class="va">mod_list_kenward</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html">as.list</a></span><span class="op">(</span><span class="va">mod_list</span><span class="op">)</span></span>
<span><span class="va">mod_list_kenward</span><span class="op">$</span><span class="va">tidy</span><span class="op">$</span><span class="va">p.value</span> <span class="op">&lt;-</span> <span class="fu">parameters</span><span class="fu">::</span><span class="fu"><a href="https://easystats.github.io/parameters/reference/p_value_kenward.html">p_value_kenward</a></span><span class="op">(</span><span class="va">mod</span><span class="op">)</span><span class="op">$</span><span class="va">p</span></span>
<span></span>
<span><span class="fu"><a href="https://modelsummary.com/man/modelsummary.html">modelsummary</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/list.html">list</a></span><span class="op">(</span><span class="st">"Wald"</span> <span class="op">=</span> <span class="va">mod_list</span>, <span class="st">"Kenward"</span> <span class="op">=</span> <span class="va">mod_list_kenward</span><span class="op">)</span>, </span>
<span>            statistic <span class="op">=</span> <span class="st">"{std.error} ({p.value}) {stars}"</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output-display">
<!-- preamble start -->

    <script>

      function styleCell_od1rdxye34pwsll0mvdz(i, j, css_id) {
          var table = document.getElementById("tinytable_od1rdxye34pwsll0mvdz");
          var cell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
          if (cell) {
              console.log(`Styling cell at (${i}, ${j}) with class ${css_id}`);
              cell.classList.add(css_id);
          } else {
              console.warn(`Cell at (${i}, ${j}) not found.`);
          }
      }
      function spanCell_od1rdxye34pwsll0mvdz(i, j, rowspan, colspan) {
        var table = document.getElementById("tinytable_od1rdxye34pwsll0mvdz");
        const targetCell = table.querySelector(`[data-row="${i}"][data-col="${j}"]`);
        if (!targetCell) {
          console.warn(`Cell at (${i}, ${j}) not found.`);
        }

        // Get all cells that need to be removed
        const cellsToRemove = [];
        for (let r = 0; r < rowspan; r++) {
          for (let c = 0; c < colspan; c++) {
            if (r === 0 && c === 0) continue; // Skip the target cell
            const cell = table.querySelector(`[data-row="${i + r}"][data-col="${j + c}"]`);
            if (cell) {
              cellsToRemove.push(cell);
            }
          }
        }

        // Remove all cells
        cellsToRemove.forEach(cell => cell.remove());

        // Set rowspan and colspan of the target cell if it exists
        if (targetCell) {
          targetCell.rowSpan = rowspan;
          targetCell.colSpan = colspan;
        }
      }
      // tinytable span after
      window.addEventListener('load', function () {
          var cellsToStyle = [
            // tinytable style arrays after
          { positions: [ { i: '11', j: 1 }, { i: '11', j: 2 },  ], css_id: 'tinytable_css_63xtxnfaytmg5ffy4z03',}, 
          { positions: [ { i: '4', j: 2 }, { i: '4', j: 1 },  ], css_id: 'tinytable_css_29hg1zl7pbnpo7uvzq62',}, 
          { positions: [ { i: '1', j: 1 }, { i: '2', j: 1 }, { i: '3', j: 1 }, { i: '5', j: 1 }, { i: '6', j: 1 }, { i: '7', j: 1 }, { i: '5', j: 2 }, { i: '9', j: 1 }, { i: '10', j: 1 }, { i: '3', j: 2 }, { i: '8', j: 1 }, { i: '1', j: 2 }, { i: '2', j: 2 }, { i: '7', j: 2 }, { i: '8', j: 2 }, { i: '9', j: 2 }, { i: '6', j: 2 }, { i: '10', j: 2 },  ], css_id: 'tinytable_css_igworufj23zpzroa3znz',}, 
          { positions: [ { i: '0', j: 1 }, { i: '0', j: 2 },  ], css_id: 'tinytable_css_bhg45vkms2ima27ilohe',}, 
          { positions: [ { i: '11', j: 0 },  ], css_id: 'tinytable_css_ehjv1u33f7umi18485xk',}, 
          { positions: [ { i: '4', j: 0 },  ], css_id: 'tinytable_css_5srx5bs7wmjtevtw246u',}, 
          { positions: [ { i: '1', j: 0 }, { i: '2', j: 0 }, { i: '3', j: 0 }, { i: '8', j: 0 }, { i: '5', j: 0 }, { i: '6', j: 0 }, { i: '7', j: 0 }, { i: '9', j: 0 }, { i: '10', j: 0 },  ], css_id: 'tinytable_css_g4y6zc0k708efz1xzefe',}, 
          { positions: [ { i: '0', j: 0 },  ], css_id: 'tinytable_css_o0jy9wy90sss5w2p2gem',}, 
          ];

          // Loop over the arrays to style the cells
          cellsToStyle.forEach(function (group) {
              group.positions.forEach(function (cell) {
                  styleCell_od1rdxye34pwsll0mvdz(cell.i, cell.j, group.css_id);
              });
          });
      });
    </script><style>
      /* tinytable css entries after */
      .table td.tinytable_css_63xtxnfaytmg5ffy4z03, .table th.tinytable_css_63xtxnfaytmg5ffy4z03 { text-align: center; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_29hg1zl7pbnpo7uvzq62, .table th.tinytable_css_29hg1zl7pbnpo7uvzq62 { text-align: center; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_igworufj23zpzroa3znz, .table th.tinytable_css_igworufj23zpzroa3znz { text-align: center; }
      .table td.tinytable_css_bhg45vkms2ima27ilohe, .table th.tinytable_css_bhg45vkms2ima27ilohe { text-align: center; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
      .table td.tinytable_css_ehjv1u33f7umi18485xk, .table th.tinytable_css_ehjv1u33f7umi18485xk { text-align: left; border-bottom: solid #d3d8dc 0.1em; }
      .table td.tinytable_css_5srx5bs7wmjtevtw246u, .table th.tinytable_css_5srx5bs7wmjtevtw246u { text-align: left; border-bottom: solid black 0.05em; }
      .table td.tinytable_css_g4y6zc0k708efz1xzefe, .table th.tinytable_css_g4y6zc0k708efz1xzefe { text-align: left; }
      .table td.tinytable_css_o0jy9wy90sss5w2p2gem, .table th.tinytable_css_o0jy9wy90sss5w2p2gem { text-align: left; border-top: solid #d3d8dc 0.1em; border-bottom: solid #d3d8dc 0.05em; }
    </style>
<div class="container">
      <table class="table table-borderless" id="tinytable_od1rdxye34pwsll0mvdz" style="width: auto; margin-left: auto; margin-right: auto;" data-quarto-disable-processing="true">
<thead><tr>
<th scope="col" data-row="0" data-col="0"> </th>
                <th scope="col" data-row="0" data-col="1">Wald</th>
                <th scope="col" data-row="0" data-col="2">Kenward</th>
              </tr></thead>
<tbody>
<tr>
<td data-row="1" data-col="0">(Intercept)</td>
                  <td data-row="1" data-col="1">-5.159</td>
                  <td data-row="1" data-col="2">-5.159</td>
                </tr>
<tr>
<td data-row="2" data-col="0"></td>
                  <td data-row="2" data-col="1">6.409 (0.428)</td>
                  <td data-row="2" data-col="2">6.409 (0.680)</td>
                </tr>
<tr>
<td data-row="3" data-col="0">drat</td>
                  <td data-row="3" data-col="1">7.045</td>
                  <td data-row="3" data-col="2">7.045</td>
                </tr>
<tr>
<td data-row="4" data-col="0"></td>
                  <td data-row="4" data-col="1">1.736 (
                  </td>
<td data-row="4" data-col="2">1.736 (0.086) +</td>
                </tr>
<tr>
<td data-row="5" data-col="0">Num.Obs.</td>
                  <td data-row="5" data-col="1">32</td>
                  <td data-row="5" data-col="2">32</td>
                </tr>
<tr>
<td data-row="6" data-col="0">R2 Marg.</td>
                  <td data-row="6" data-col="1">0.402</td>
                  <td data-row="6" data-col="2">0.402</td>
                </tr>
<tr>
<td data-row="7" data-col="0">R2 Cond.</td>
                  <td data-row="7" data-col="1">0.440</td>
                  <td data-row="7" data-col="2">0.440</td>
                </tr>
<tr>
<td data-row="8" data-col="0">AIC</td>
                  <td data-row="8" data-col="1">188.7</td>
                  <td data-row="8" data-col="2">188.7</td>
                </tr>
<tr>
<td data-row="9" data-col="0">BIC</td>
                  <td data-row="9" data-col="1">194.6</td>
                  <td data-row="9" data-col="2">194.6</td>
                </tr>
<tr>
<td data-row="10" data-col="0">ICC</td>
                  <td data-row="10" data-col="1">0.1</td>
                  <td data-row="10" data-col="2">0.1</td>
                </tr>
<tr>
<td data-row="11" data-col="0">RMSE</td>
                  <td data-row="11" data-col="1">4.28</td>
                  <td data-row="11" data-col="2">4.28</td>
                </tr>
</tbody>
</table>
</div>
<!-- hack to avoid NA insertion in last line -->
</div>
</div>


</section></main><!-- /main --><script id="quarto-html-after-body" type="application/javascript">
  window.document.addEventListener("DOMContentLoaded", function (event) {
    const icon = "";
    const anchorJS = new window.AnchorJS();
    anchorJS.options = {
      placement: 'right',
      icon: icon
    };
    anchorJS.add('.anchored');
    const isCodeAnnotation = (el) => {
      for (const clz of el.classList) {
        if (clz.startsWith('code-annotation-')) {                     
          return true;
        }
      }
      return false;
    }
    const onCopySuccess = function(e) {
      // button target
      const button = e.trigger;
      // don't keep focus
      button.blur();
      // flash "checked"
      button.classList.add('code-copy-button-checked');
      var currentTitle = button.getAttribute("title");
      button.setAttribute("title", "Copied!");
      let tooltip;
      if (window.bootstrap) {
        button.setAttribute("data-bs-toggle", "tooltip");
        button.setAttribute("data-bs-placement", "left");
        button.setAttribute("data-bs-title", "Copied!");
        tooltip = new bootstrap.Tooltip(button, 
          { trigger: "manual", 
            customClass: "code-copy-button-tooltip",
            offset: [0, -8]});
        tooltip.show();    
      }
      setTimeout(function() {
        if (tooltip) {
          tooltip.hide();
          button.removeAttribute("data-bs-title");
          button.removeAttribute("data-bs-toggle");
          button.removeAttribute("data-bs-placement");
        }
        button.setAttribute("title", currentTitle);
        button.classList.remove('code-copy-button-checked');
      }, 1000);
      // clear code selection
      e.clearSelection();
    }
    const getTextToCopy = function(trigger) {
        const codeEl = trigger.previousElementSibling.cloneNode(true);
        for (const childEl of codeEl.children) {
          if (isCodeAnnotation(childEl)) {
            childEl.remove();
          }
        }
        return codeEl.innerText;
    }
    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
      text: getTextToCopy
    });
    clipboard.on('success', onCopySuccess);
    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
        text: getTextToCopy,
        container: window.document.getElementById('quarto-embedded-source-code-modal')
      });
      clipboardModal.on('success', onCopySuccess);
    }
      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
      var mailtoRegex = new RegExp(/^mailto:/);
        var filterRegex = new RegExp('/' + window.location.host + '/');
      var isInternal = (href) => {
          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
      }
      // Inspect non-navigation links and adorn them if external
     var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
      for (var i=0; i<links.length; i++) {
        const link = links[i];
        if (!isInternal(link.href)) {
          // undo the damage that might have been done by quarto-nav.js in the case of
          // links that we want to consider external
          if (link.dataset.originalHref !== undefined) {
            link.href = link.dataset.originalHref;
          }
        }
      }
    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
      const config = {
        allowHTML: true,
        maxWidth: 500,
        delay: 100,
        arrow: false,
        appendTo: function(el) {
            return el.parentElement;
        },
        interactive: true,
        interactiveBorder: 10,
        theme: 'quarto',
        placement: 'bottom-start',
      };
      if (contentFn) {
        config.content = contentFn;
      }
      if (onTriggerFn) {
        config.onTrigger = onTriggerFn;
      }
      if (onUntriggerFn) {
        config.onUntrigger = onUntriggerFn;
      }
      window.tippy(el, config); 
    }
    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
    for (var i=0; i<noterefs.length; i++) {
      const ref = noterefs[i];
      tippyHover(ref, function() {
        // use id or data attribute instead here
        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
        try { href = new URL(href).hash; } catch {}
        const id = href.replace(/^#\/?/, "");
        const note = window.document.getElementById(id);
        if (note) {
          return note.innerHTML;
        } else {
          return "";
        }
      });
    }
    const xrefs = window.document.querySelectorAll('a.quarto-xref');
    const processXRef = (id, note) => {
      // Strip column container classes
      const stripColumnClz = (el) => {
        el.classList.remove("page-full", "page-columns");
        if (el.children) {
          for (const child of el.children) {
            stripColumnClz(child);
          }
        }
      }
      stripColumnClz(note)
      if (id === null || id.startsWith('sec-')) {
        // Special case sections, only their first couple elements
        const container = document.createElement("div");
        if (note.children && note.children.length > 2) {
          container.appendChild(note.children[0].cloneNode(true));
          for (let i = 1; i < note.children.length; i++) {
            const child = note.children[i];
            if (child.tagName === "P" && child.innerText === "") {
              continue;
            } else {
              container.appendChild(child.cloneNode(true));
              break;
            }
          }
          if (window.Quarto?.typesetMath) {
            window.Quarto.typesetMath(container);
          }
          return container.innerHTML
        } else {
          if (window.Quarto?.typesetMath) {
            window.Quarto.typesetMath(note);
          }
          return note.innerHTML;
        }
      } else {
        // Remove any anchor links if they are present
        const anchorLink = note.querySelector('a.anchorjs-link');
        if (anchorLink) {
          anchorLink.remove();
        }
        if (window.Quarto?.typesetMath) {
          window.Quarto.typesetMath(note);
        }
        if (note.classList.contains("callout")) {
          return note.outerHTML;
        } else {
          return note.innerHTML;
        }
      }
    }
    for (var i=0; i<xrefs.length; i++) {
      const xref = xrefs[i];
      tippyHover(xref, undefined, function(instance) {
        instance.disable();
        let url = xref.getAttribute('href');
        let hash = undefined; 
        if (url.startsWith('#')) {
          hash = url;
        } else {
          try { hash = new URL(url).hash; } catch {}
        }
        if (hash) {
          const id = hash.replace(/^#\/?/, "");
          const note = window.document.getElementById(id);
          if (note !== null) {
            try {
              const html = processXRef(id, note.cloneNode(true));
              instance.setContent(html);
            } finally {
              instance.enable();
              instance.show();
            }
          } else {
            // See if we can fetch this
            fetch(url.split('#')[0])
            .then(res => res.text())
            .then(html => {
              const parser = new DOMParser();
              const htmlDoc = parser.parseFromString(html, "text/html");
              const note = htmlDoc.getElementById(id);
              if (note !== null) {
                const html = processXRef(id, note);
                instance.setContent(html);
              } 
            }).finally(() => {
              instance.enable();
              instance.show();
            });
          }
        } else {
          // See if we can fetch a full url (with no hash to target)
          // This is a special case and we should probably do some content thinning / targeting
          fetch(url)
          .then(res => res.text())
          .then(html => {
            const parser = new DOMParser();
            const htmlDoc = parser.parseFromString(html, "text/html");
            const note = htmlDoc.querySelector('main.content');
            if (note !== null) {
              // This should only happen for chapter cross references
              // (since there is no id in the URL)
              // remove the first header
              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
                note.children[0].remove();
              }
              const html = processXRef(null, note);
              instance.setContent(html);
            } 
          }).finally(() => {
            instance.enable();
            instance.show();
          });
        }
      }, function(instance) {
      });
    }
        let selectedAnnoteEl;
        const selectorForAnnotation = ( cell, annotation) => {
          let cellAttr = 'data-code-cell="' + cell + '"';
          let lineAttr = 'data-code-annotation="' +  annotation + '"';
          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
          return selector;
        }
        const selectCodeLines = (annoteEl) => {
          const doc = window.document;
          const targetCell = annoteEl.getAttribute("data-target-cell");
          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
          const lineIds = lines.map((line) => {
            return targetCell + "-" + line;
          })
          let top = null;
          let height = null;
          let parent = null;
          if (lineIds.length > 0) {
              //compute the position of the single el (top and bottom and make a div)
              const el = window.document.getElementById(lineIds[0]);
              top = el.offsetTop;
              height = el.offsetHeight;
              parent = el.parentElement.parentElement;
            if (lineIds.length > 1) {
              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
              height = bottom - top;
            }
            if (top !== null && height !== null && parent !== null) {
              // cook up a div (if necessary) and position it 
              let div = window.document.getElementById("code-annotation-line-highlight");
              if (div === null) {
                div = window.document.createElement("div");
                div.setAttribute("id", "code-annotation-line-highlight");
                div.style.position = 'absolute';
                parent.appendChild(div);
              }
              div.style.top = top - 2 + "px";
              div.style.height = height + 4 + "px";
              div.style.left = 0;
              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
              if (gutterDiv === null) {
                gutterDiv = window.document.createElement("div");
                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
                gutterDiv.style.position = 'absolute';
                const codeCell = window.document.getElementById(targetCell);
                const gutter = codeCell.querySelector('.code-annotation-gutter');
                gutter.appendChild(gutterDiv);
              }
              gutterDiv.style.top = top - 2 + "px";
              gutterDiv.style.height = height + 4 + "px";
            }
            selectedAnnoteEl = annoteEl;
          }
        };
        const unselectCodeLines = () => {
          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
          elementsIds.forEach((elId) => {
            const div = window.document.getElementById(elId);
            if (div) {
              div.remove();
            }
          });
          selectedAnnoteEl = undefined;
        };
          // Handle positioning of the toggle
      window.addEventListener(
        "resize",
        throttle(() => {
          elRect = undefined;
          if (selectedAnnoteEl) {
            selectCodeLines(selectedAnnoteEl);
          }
        }, 10)
      );
      function throttle(fn, ms) {
      let throttle = false;
      let timer;
        return (...args) => {
          if(!throttle) { // first call gets through
              fn.apply(this, args);
              throttle = true;
          } else { // all the others get throttled
              if(timer) clearTimeout(timer); // cancel #2
              timer = setTimeout(() => {
                fn.apply(this, args);
                timer = throttle = false;
              }, ms);
          }
        };
      }
        // Attach click handler to the DT
        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
        for (const annoteDlNode of annoteDls) {
          annoteDlNode.addEventListener('click', (event) => {
            const clickedEl = event.target;
            if (clickedEl !== selectedAnnoteEl) {
              unselectCodeLines();
              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
              if (activeEl) {
                activeEl.classList.remove('code-annotation-active');
              }
              selectCodeLines(clickedEl);
              clickedEl.classList.add('code-annotation-active');
            } else {
              // Unselect the line
              unselectCodeLines();
              clickedEl.classList.remove('code-annotation-active');
            }
          });
        }
    const findCites = (el) => {
      const parentEl = el.parentElement;
      if (parentEl) {
        const cites = parentEl.dataset.cites;
        if (cites) {
          return {
            el,
            cites: cites.split(' ')
          };
        } else {
          return findCites(el.parentElement)
        }
      } else {
        return undefined;
      }
    };
    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
    for (var i=0; i<bibliorefs.length; i++) {
      const ref = bibliorefs[i];
      const citeInfo = findCites(ref);
      if (citeInfo) {
        tippyHover(citeInfo.el, function() {
          var popup = window.document.createElement('div');
          citeInfo.cites.forEach(function(cite) {
            var citeDiv = window.document.createElement('div');
            citeDiv.classList.add('hanging-indent');
            citeDiv.classList.add('csl-entry');
            var biblioDiv = window.document.getElementById('ref-' + cite);
            if (biblioDiv) {
              citeDiv.innerHTML = biblioDiv.innerHTML;
            }
            popup.appendChild(citeDiv);
          });
          return popup.innerHTML;
        });
      }
    }
  });
  </script><nav class="page-navigation"><div class="nav-page nav-page-previous">
      <a href="../vignettes/modelplot.html" class="pagination-link" aria-label="Model Plots">
        <i class="bi bi-arrow-left-short"></i> <span class="nav-page-text">Model Plots</span>
      </a>          
  </div>
  <div class="nav-page nav-page-next">
      <a href="../vignettes/appearance.html" class="pagination-link" aria-label="Themes and Styles">
        <span class="nav-page-text">Themes and Styles</span> <i class="bi bi-arrow-right-short"></i>
      </a>
  </div>
</nav>
</div> <!-- /content -->



</body></html>